using System;

using NUnit.Framework;

using StructureMap.AutoMocking;

using StructureMap.TypeMockAutoMocker;

namespace StructureMap.TypeMockAutoMocker
{
	public abstract class AutoMockerTesterBase<TCutWithAbstractMock, TCutWithConcreteMock> where TCutWithAbstractMock: class, IConsumer where TCutWithConcreteMock: class, IConsumer
	{
		protected abstract MockMode MockMode { get; }

		protected AutoMocker<T> createAutoMocker<T>() where T: class
		{
			var mocker = new TypeMockAutoMocker<T>();
			return mocker;
		}

		protected AutoMocker<TCutWithAbstractMock> createAutoMockerWithAbstractMock()
		{
			return createAutoMocker<TCutWithAbstractMock>();
		}

		protected AutoMocker<TCutWithConcreteMock> createAutoMockerWithConcreteMock()
		{
			return createAutoMocker<TCutWithConcreteMock>();
		}

		[Test]
		public void AbstractMockReturnsDefaultValues()
		{
			var consumerAutoMocker = createAutoMockerWithAbstractMock();

			// Act
			consumerAutoMocker.PartialMockTheClassUnderTest();
			Assert.AreEqual(0, consumerAutoMocker.ClassUnderTest.CallMock(7), "the mock didn't return the expected default value. Somehow the AutoMocker hasn't setup it correctly");
		}

		[Test]
		public void ConcreteMockIsCalled()
		{
			var consumerAutoMocker = createAutoMockerWithConcreteMock();

			// Act
			consumerAutoMocker.PartialMockTheClassUnderTest();
			Assert.AreEqual(7, consumerAutoMocker.ClassUnderTest.CallMock(7), "the mock didn't behave as expected. Somehow the AutoMocker hasn't setup it correctly");
		}
	}
}